package cnsatmsmart.automation.mmi.view.layers;

import cnsatmsmart.automation.mmi.helper.utilities.GlobalEnvVars;
import com.bbn.openmap.Layer;
import com.bbn.openmap.event.ProjectionEvent;
import com.bbn.openmap.omGraphics.OMGraphicConstants;
import com.bbn.openmap.omGraphics.OMGraphicList;
import com.bbn.openmap.omGraphics.OMPoly;
import com.bbn.openmap.proj.Projection;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import cnsatmsmart.automation.mmi.model.data.TSafe.Airway;
import cnsatmsmart.automation.mmi.model.data.TSafe.Fix;
import cnsatmsmart.automation.mmi.model.database.DataBase;

/**
 * @author SIK - PTIK, BPPT
 **/

public class AirwaysLayer extends Layer {
    /* const */
        private static final Color FIXES_COLOR = new Color (192, 192, 192);
            //nilai warna default untuk pewarnaan pada penggambaran airways yang merupakan instance dari kelas AirwaysLayer

    /* atribut - atribut yang dimiliki oleh kelas AirwaysLayer */
        private OMGraphicList graphics = new OMGraphicList();
        private Projection projection = null;

        private List < Airway > airways = null;

        boolean isCreated = false;
        
        private static String db_Connection = "jdbc:mysql:///MMI?user=" + GlobalEnvVars.db_Username + "&password=" + GlobalEnvVars.db_Password;
    
    /* constructor - user defined ctor, no default ctor */
        // <editor-fold defaultstate="collapsed" desc="ctor">
        /**
         * menginstansiasi object AirwaysLayer<br />
         * #do nothing ctor
         */
        public AirwaysLayer() { }
        // </editor-fold>

    /* getter */
        /**
         * mengembalikan Fix dengan ID = ID dari fixes, null jika fixes tidak mengandung Fix dengan ID = ID
         * @param fixes List < Fix > senarai fixes yang merupakan container dari fix-fix
         * @param ID String yang merupakan ID dari Fix yang dicari
         * @return Fix yang mana memiliki ID = ID
         */
        public static Fix getFix(List < Fix > fixes, String ID) {
            Iterator < Fix > fixesIter = fixes.iterator();
            while (fixesIter.hasNext()) {
                Fix fix = fixesIter.next();
                if (fix.getID().equals(ID)) {
                    return (fix);
                }
            }

            return (null);
        }
        /**
         * melakukan retrieve basis data untuk mendapatkan List < Airway >
         * @return List < Airway > yang merupakan senarai airways seperti yang terdapat pada basis data tabel airways
         */
        public static List < Airway > getAirways() {
            List < Airway > RetVal = new ArrayList < Airway >();
            List < Fix > allFixes = new ArrayList < Fix >();
            allFixes.addAll(FixesLayer.getFixes());
            allFixes.addAll(FixesLayer.getAirports());
            allFixes.addAll(FixesLayer.getNavaids());

            try {
                DataBase db = new DataBase(db_Connection);
                db.createQuery("SELECT * FROM airways");
                
                while (db.getResultSet().next()) {
                    Airway airway = new Airway(db.getResultSet().getString("ID_Airways"));
                    String stringFix = db.getResultSet().getString("Path_Airways");
                    String[] stringFixes = stringFix.split(";");
                    for (String str : stringFixes) {
                        Fix f = getFix(allFixes, str);
                        if (f != null) {
                            airway.addFix(f);
                        }
                    }
                    RetVal.add(airway);
                }
            } catch (Exception e) {
                System.out.println("failed to connect to database");
            }

            return (RetVal);
        }

    /* setter */
        /**
         * mengupdate graphics dari layer tanpa melakukan retrieve basis data jika sudah pernah dilakukan sebelumnya
         * @param graphics OMGraphicList yang merupakan container untuk menampung graphic yang akan diproyeksikan ke layar
         * @return OMGraphicList yang mengacu kepada graphics
         */
        public OMGraphicList setAirways(OMGraphicList graphics) {
            return (setAirways(graphics, false));
        }
        /**
         * mengupdate graphics dari layer
         * @param graphics OMGraphicList yang merupakan container untuk menampung graphic yang akan diproyeksikan ke layar
         * @param updateAirways boolean yang menentukan apakah pengupdatean tampilan didahului dengan proses retrieve basis data sebelumnya atau tidak :<br />
         *                      bernilai true jika melakukan retrieve basis data dan false jika sebaliknya
         * @return OMGraphicList yang mengacu kepada graphics
         */
        public OMGraphicList setAirways(OMGraphicList graphics, boolean updateAirways) {
            graphics.clear();
            
            if ((this.airways == null) || (updateAirways)) {
                this.airways = getAirways();
            }
            if ((this.airways != null) || (updateAirways)) {
                Iterator < Airway > airwaysIter = this.airways.iterator();
                while (airwaysIter.hasNext()) {
                    Airway airway = airwaysIter.next();
                    List < Fix > fixesList = (List < Fix >) airway.fixesList();
                    float LatLonPoints[] = new float[fixesList.size() * 2];
                    for (int i = 0; i < fixesList.size(); ++i) {
                        LatLonPoints[(i * 2)] = (float)fixesList.get(i).getLatitude();
                        LatLonPoints[((i * 2) + 1)] = (float)fixesList.get(i).getLongitude();
                    }
                    OMPoly polygon = new OMPoly(LatLonPoints, OMGraphicConstants.DECIMAL_DEGREES, OMGraphicConstants.LINETYPE_STRAIGHT);
                    polygon.setLinePaint(FIXES_COLOR);
                    graphics.addOMGraphic(polygon);
                }
            }

            isCreated = true;

            return (graphics);
        }

    /* method - method yang dimiliki oleh kelas AirwaysLayer */
        /**
         * mengupdate layer sesuai dengan data yang terdapat pada basis data
         */
        public void update() {
            setAirways(this.graphics);
            this.graphics.project(this.projection, true);
            repaint();
        }

    /**
     * event handler untuk event perubahan projection
     * @param pe ProjectionEvent event projection yang terjadi
     */
    public void projectionChanged(ProjectionEvent pe) {
        this.projection = (Projection) pe.getProjection().makeClone();
        if (! isCreated) {
            setAirways(this.graphics);
        }
        this.graphics.project(this.projection, true);
        repaint();
    }

    @Override
    public void paint (Graphics g) {
        this.graphics.render(g);
    }
}
